package org.bangumibuddy.security.provider;

import lombok.Data;
import org.bangumibuddy.constant.Constant;
import org.bangumibuddy.security.entity.BangumiAuthenticationToken;
import org.bangumibuddy.security.entity.BangumiUserDetail;
import org.bangumibuddy.security.service.BangumiUserDetailService;
import org.bangumibuddy.utils.JwtUtils;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.crypto.password.PasswordEncoder;
import java.util.Collections;

@Data
public class BangumiAuthenticationProvider implements AuthenticationProvider {

    private String SECRET;

    private BangumiUserDetailService userDetailsService;

    private PasswordEncoder passwordEncoder;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        //前置验证组件是否为null
        if(SECRET==null || userDetailsService==null || passwordEncoder==null){
            throw new RuntimeException("BangumiAuthenticationProvider组件未初始化");
        }

        if( authentication instanceof UsernamePasswordAuthenticationToken){
            return UserNamePasswordVerify(authentication.getName(),(String)authentication.getCredentials());
        }

        BangumiAuthenticationToken token = (BangumiAuthenticationToken) authentication;
        if (token.getToken() != null) {
            //token验证逻辑
            return TokenVerify(token);
        }

        return null;
    }


    private Authentication UserNamePasswordVerify(String userName, String password) {
        BangumiUserDetail userDetails = (BangumiUserDetail) userDetailsService.loadUserByUsername(userName);
        if (userDetails!=null && passwordEncoder.matches(password, userDetails.getPassword())) {

            //创建token
            return createToken(
                    userDetails.getUsername(), userDetails.getEmail(), userDetails.getRole());
    }
        return new BangumiAuthenticationToken();
}

    private Authentication TokenVerify(BangumiAuthenticationToken token) {
        String jwt = token.getToken();
        //验证合法性
        if ( JwtUtils.verityToken(jwt, SECRET)) {
            //获取用户名
            String userName = JwtUtils.getProperty(Constant.USERNAME, jwt, SECRET);
            String email = JwtUtils.getProperty(Constant.EMAIL, jwt, SECRET);
            String role = JwtUtils.getProperty(Constant.ROLE, jwt, SECRET);

            //创建token
            return createToken(userName, email, role);
        }

        return null;
    }

    private BangumiAuthenticationToken createToken(String userName, String email, String role) {
        BangumiAuthenticationToken authenticationToken = new BangumiAuthenticationToken(Collections.singleton(new SimpleGrantedAuthority("ROLE_"+role)));
        authenticationToken.setUserName(userName);
        authenticationToken.setEmail(email);
        authenticationToken.setRole(role);
        authenticationToken.setAuthenticated(true);
        return authenticationToken;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return BangumiAuthenticationToken.class.isAssignableFrom(authentication) || UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }
    
}